package com.gitee.cirnochat.websocket.service.impl;

import com.gitee.cirnochat.websocket.model.dto.WebSocketBroadCastMessage;
import com.gitee.cirnochat.websocket.model.dto.WebSocketUserMessage;
import com.gitee.cirnochat.websocket.model.dto.WebSocketUserNode;
import com.gitee.cirnochat.websocket.service.WebSocketService;
import com.gitee.cirnochat.websocket.service.manager.SessionManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.Collection;

import static com.gitee.cirnochat.common.constant.MQKey.CHAT_MESSAGE_ROUTE_ROUTING_KEY;

@Service
@RequiredArgsConstructor
@Slf4j
public class WebSocketServiceImpl implements WebSocketService {
    private final SimpMessagingTemplate simpMessagingTemplate;
    private final RabbitTemplate rabbitTemplate;
    private final SessionManager sessionManager;


    @Override
    public void sendMessageToOnlineDevices(WebSocketUserMessage message) {
        Collection<WebSocketUserNode> users = sessionManager.getAllDevices(Long.parseLong(message.getUserId())).values();
        if (users.isEmpty()) {
            log.warn("用户 [{}] 没有在线设备，无法发送消息", message.getUserId());
            return;
        }
        for (WebSocketUserNode user : users) {
            log.info("发送消息到用户 [{}] 的设备 [{}]，节点 ID: {}", message.getUserId(), user.getDeviceId(), user.getNodeId());
            if (sessionManager.isDeviceAtLocalNode(user)) {
                // 如果设备在当前节点，直接发送消息
                sendMessageToUser(message);
            } else {
                // 如果设备不在当前节点，发送到消息队列
                rabbitTemplate.convertAndSend(message.getSubscribeChannel() + '-' + user.getNodeId(), message);
            }
        }
    }


    @Override
    public void sendMessageToOnlineDevicesExcludeCurrent(WebSocketUserMessage message) {
        Collection<WebSocketUserNode> users = sessionManager.getAllDevices(Long.parseLong(message.getUserId())).values();
        if (users.isEmpty()) {
            log.warn("用户 [{}] 没有在线设备，无法发送消息", message.getUserId());
            return;
        }
        for (WebSocketUserNode user : users) {
            log.info("发送消息到用户 [{}] 的设备 [{}]，节点 ID: {}", message.getUserId(), user.getDeviceId(), user.getNodeId());
            if (sessionManager.isDeviceAtLocalNode(user)) {
                return;
            } else {
                // 如果设备不在当前节点，发送到消息队列
                rabbitTemplate.convertAndSend(CHAT_MESSAGE_ROUTE_ROUTING_KEY + '-' + user.getNodeId(),message);
            }
        }
    }


    @Override
    public void sendMessageToUser(WebSocketUserMessage message) {
        simpMessagingTemplate.convertAndSendToUser(message.getUserId(), message.getSubscribeChannel(), message.getPayload());
    }

    @Override
    public void sendMessageToAll(WebSocketBroadCastMessage message) {
        simpMessagingTemplate.convertAndSend(message.getSubscribeChannel(), message.getPayload());
    }
}
